package com.songshuai.webapi.permission.controller;


import com.songshuai.webapi.baseapi.enumerations.ResultStatus;
import com.songshuai.webapi.baseapi.exception.BusinessException;
import com.songshuai.webapi.baseapi.pojo.BaseParmDto;
import com.songshuai.webapi.baseapi.pojo.QueryPageRes;
import com.songshuai.webapi.baseapi.pojo.QueryResponse;
import com.songshuai.webapi.baseapi.utils.OssUploadUtil;
import com.songshuai.webapi.baseapi.utils.PropertiesUtil;
import com.songshuai.webapi.baseapi.utils.RequestParamValidUtil;
import com.songshuai.webapi.baseapi.utils.SnowFlakeUtil;
import com.songshuai.webapi.common.upload.BaseUploadFile;
import com.songshuai.webapi.permission.Util.PageUtil;
import com.songshuai.webapi.permission.config.redislock.RedisLockImpl;
import com.songshuai.webapi.permission.dto.po.UsersResPojo;
import com.songshuai.webapi.permission.dto.request.Departments.*;
import com.songshuai.webapi.permission.dto.request.DepartmentsAddReqDto;
import com.songshuai.webapi.permission.dto.request.DepartmentsUpdateRelationAddReqDto;
import com.songshuai.webapi.permission.dto.request.DepartmentsUpdateReqDto;
import com.songshuai.webapi.permission.dto.response.DepartmentResDto;
import com.songshuai.webapi.permission.dto.response.DepartmentsChildResDto;
import com.songshuai.webapi.permission.dto.response.UsersResDto;
import com.songshuai.webapi.permission.model.YxDepartments;
import com.songshuai.webapi.permission.model.YxUsers;
import com.songshuai.webapi.permission.service.DepartmentsService;
import com.songshuai.webapi.permission.service.UsersService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@Api("部门管理")
@RestController
@RequestMapping("/api/departments/")
public class DepartmentsController extends BaseController{


    @Autowired
    private DepartmentsService departmentsService;
    @Autowired
    private UsersService usersService;

    @Autowired
    private OssUploadUtil uploadUtil;

    @Value("${file.basePath}")
    private String fileBasePath;


    @Autowired
    private SnowFlakeUtil snowFlakeUtil;


    @Autowired
    private StringRedisTemplate redisTemplate;

    @ApiOperation(value = "新增部门")
    @PostMapping("addDepartment")
    public QueryResponse<DepartmentResDto> addDepartment(@RequestBody @Valid DepartmentsAddReqDto req, BindingResult result){
        if (result.hasErrors()){
            return new QueryResponse(ResultStatus.ERROR_INVALID_ARGUMENT.getErrorCode(), RequestParamValidUtil.getBindingResultMessage(result));
        }
        try {
            YxDepartments yxDepartments = new YxDepartments();
            PropertiesUtil.copyProperties(req,yxDepartments);
            yxDepartments.setCreateBy(getUserBaseInfo().getId());
            yxDepartments.setUpdateBy(getUserBaseInfo().getId());
            if (departmentsService.addDepartment(yxDepartments)){
                return QueryResponse.setResData(new DepartmentResDto() {{
                    setId(yxDepartments.getId());
                    setName(yxDepartments.getName());
                }});
            }
        } catch (Exception e) {
            log.error("/api/departments/addDepartment",e);
        }

        return new QueryResponse(ResultStatus.ERROR_CREATE_FAILED);
    }


    /*@Deprecated
    @ApiOperation(value = "根据部门id获取全部部门树,该方法放弃使用")
    @GetMapping("queryAllList")
    public QueryResponse<DepartmentsListResDto> queryAllList(@RequestParam Integer id){
        return QueryResponse.setResData(departmentsService.queryAllList(id));
    }
*/


    /*@Deprecated
    @ApiOperation(value = "根据部门id获取最近的父级根节点")
    @GetMapping("queryParent")
    public QueryResponse<List<DepartmentChildResDto>> queryParent(){
        return QueryResponse.setResData(departmentsService.queryRootParentList(getUserBaseInfo()));
    }*/


    /*@Deprecated
    @ApiOperation(value = "根据部门id获取子部门")
    @GetMapping("queryChildList")
    public QueryResponse<List<DepartmentChildResDto>> queryChildList(@RequestParam("id") Integer id,
                                                                   @RequestParam("userDepartmentId") Integer userDepartmentId){
        return QueryResponse.setResData(departmentsService.selectListAndChildNumById(id,userDepartmentId));
    }*/


    @ApiOperation(value = "根据部门id获当前部门信息")
    @GetMapping("queryDepartmentById")
    public QueryResponse<DepartmentResDto> queryDepartmentById(@RequestParam("id") Integer id){
        return QueryResponse.setResData(departmentsService.selectByPrimaryKey(id));
    }




    @ApiOperation(value = "修改部门层级关系（页面拖动修改）")
    @PostMapping("updateDepartmentsRelation")
    public QueryResponse updateDepartmentsRelation(@RequestBody @Valid DepartmentsUpdateRelationAddReqDto request,BindingResult result){
        if (result.hasErrors()){
            return new QueryResponse(ResultStatus.ERROR_INVALID_ARGUMENT.getErrorCode(), RequestParamValidUtil.getBindingResultMessage(result));
        }
        RedisLockImpl redisLock = new RedisLockImpl(redisTemplate, 5);
        try {
            long lock = redisLock.lock("/api/departments/updateDepartmentsRelation", Thread.currentThread().getName());
            if (-1!=lock){
                Boolean flag = departmentsService.updateDepartmentsRelation(request,getUserId());
                if (flag){
                    return new QueryResponse();
                }
            }
        } catch (Exception e) {
            log.error("/api/departments/updateDepartmentsRelation",e);
        } finally {
            redisLock.unlock("/api/departments/updateDepartmentsRelation",5L,Thread.currentThread().getName());
        }
        return new QueryResponse(ResultStatus.ERROR_UPDATE_FAILED);
    }



    @ApiOperation(value = "修改部门信息")
    @PostMapping("updateDepartments")
    public QueryResponse updateDepartments(@RequestBody @Valid DepartmentsUpdateReqDto request,BindingResult result){
        if (result.hasErrors()){
            return new QueryResponse(ResultStatus.ERROR_INVALID_ARGUMENT.getErrorCode(), RequestParamValidUtil.getBindingResultMessage(result));
        }
        try {
            YxDepartments yxDepartments = new YxDepartments();
            PropertiesUtil.copyProperties(request,yxDepartments);
            yxDepartments.setUpdateBy(getUserId());
            if (departmentsService.updateDepartment(yxDepartments)){
                return QueryResponse.setResData(new DepartmentResDto() {{
                    setId(yxDepartments.getId());
                    setName(yxDepartments.getName());
                }});
            }
        } catch (Exception e) {
            log.error("/api/departments/updateDepartments", e);
        }
        return new QueryResponse(ResultStatus.ERROR_UPDATE_FAILED);
    }


    @ApiOperation(value = "删除部门")
    @PostMapping("deleteDepartments")
    public QueryResponse deleteDepartments(@RequestParam("id") Integer id){
        if (departmentsService.deleteDepartments(id,getUserBaseInfo().getId())){
            return new QueryResponse();
        }
        return new QueryResponse(ResultStatus.ERROR_DELETE_FAILED.getErrorCode(),"删除失败，请查看该部门下是否有关联用户或该部门已被删除");
    }


    /**
     * 查询用户列表
     */
    //@Cacheable(value = "queryUsersForStr")
    @GetMapping("queryUsersForStr")
    public QueryResponse queryUsersForStr(@RequestParam("ids") String ids) {

        try{
            List<YxUsers> users = usersService.queryUsersForStr(ids);
            return QueryResponse.setResData(users);
        } catch (Exception ex) {
            log.error("api/departments/queryUsersForStr", ex);
            throw new BusinessException(ex.getMessage(), ResultStatus.FAILOfficial);
        }

    }

    /**
     * @param request
     * @return
     */
    @ApiOperation(value = "查找部门用户")
    @RequestMapping(value = "userList", method = RequestMethod.POST)
    public QueryResponse<List<UsersResDto>> userList(@RequestBody BaseParmDto<UserListReqDto> request) {

        try{

            PageUtil page = usersService.selectUsersForDeparent(request);
            List<UsersResDto> usersResDtos = (List<UsersResDto>)page.getLists();
            return QueryPageRes.setQueryResponseData(usersResDtos,page.getTotalSize()==null?0L:page.getTotalSize().longValue());

        } catch (Exception ex) {
            log.error("api/departments/userList", ex);
            throw new BusinessException(ex.getMessage(), ResultStatus.FAILOfficial);
        }
    }


    /**
     * @param
     * @return
     */
    @ApiOperation(value = "新增部门用户")
    @RequestMapping(value = "addDepartmentUser", method = RequestMethod.POST)
    public QueryResponse addDepartmentUser(@RequestBody AddDepartmentUserReqDto request) {

        try{
            usersService.insertDepartmentUser(request);
            return QueryResponse.setResData(null);

        } catch (Exception ex) {
            log.error("api/departments/addDepartmentUser", ex);
            throw new BusinessException(ex.getMessage(), ResultStatus.FAILOfficial);
        }
    }




    /**
     *  departmentId 归属部门
     *  userIds 用户列表（1，2，3）
     *  isRelieve 是否解除用户原关系 1：是
     * @return
     */
    @ApiOperation(value = "调入已有用户/设置部门关系")
    @RequestMapping(value = "updateUserDepartment", method = RequestMethod.POST)
    public QueryResponse updateUserDepartment(@RequestBody UpdateUserDepartmentReqDto request) {

        try{

            usersService.updateUserDepartment(request);
            return QueryResponse.setResData(null);

        } catch (Exception ex) {
            log.error("api/departments/updateUserDepartment", ex);
            throw new BusinessException(ex.getMessage(), ResultStatus.FAILOfficial);
        }
    }



    @ApiOperation(value = "设置部门领导")
    @RequestMapping(value = "updateDepartmentsLeader", method = RequestMethod.POST)
    public QueryResponse updateDepartmentsLeader(@RequestBody UpdateDepartmentsLeaderReqDto request) {

        try{
            usersService.updateDepartmentsLeader(request);
            return QueryResponse.setResData(null);

        } catch (Exception ex) {
            log.error("api/departments/updateDepartmentsLeader", ex);
            throw new BusinessException(ex.getMessage(), ResultStatus.FAILOfficial);
        }
    }


    @ApiOperation(value = "设置部门领导-人员列表")
    @RequestMapping(value = "updateDepartmentsLeaderUserList", method = RequestMethod.POST)
    public QueryResponse updateDepartmentsLeaderUserList(@RequestBody UpdateDepartmentsLeaderUserListReqDto request) {

        try{
            List<UsersResPojo> usersResPojos =  usersService.updateDepartmentsLeaderUserList(request);

            return QueryResponse.setResData(usersResPojos);

        } catch (Exception ex) {
            log.error("api/departments/updateDepartmentsLeaderUserList", ex);
            throw new BusinessException(ex.getMessage(), ResultStatus.FAILOfficial);
        }
    }


    @ApiOperation(value = "设置部门领导-回填人员列表")
    @RequestMapping(value = "updateDepartmentsLeaderBackUserList", method = RequestMethod.POST)
    public QueryResponse updateDepartmentsLeaderBackUserList(@RequestBody UpdateDepartmentsLeaderBackUserListReqDto request) {

        try{

            List<UsersResPojo> usersResPojos =  usersService.updateDepartmentsLeaderBackUserList(request);

            return QueryResponse.setResData(usersResPojos);

        } catch (Exception ex) {
            log.error("api/departments/updateDepartmentsLeaderBackUserList", ex);

            throw new BusinessException(ex.getMessage(), ResultStatus.FAILOfficial);
        }
    }



    @ApiOperation(value = "调入已有用户/设置部门关系-人员列表")
    @RequestMapping(value = "updateUserDepartmentUserList", method = RequestMethod.POST)
    public QueryResponse updateUserDepartmentUserList(@RequestBody UpdateUserDepartmentUserListReqDto request) {

        try{

            List<UsersResPojo> usersResPojos = usersService.updateUserDepartmentUserList(request);
            return QueryResponse.setResData(usersResPojos);

        } catch (Exception ex) {
            log.error("api/departments/updateUserDepartmentUserList", ex);
            throw new BusinessException(ex.getMessage(), ResultStatus.FAILOfficial);
        }
    }

    @ApiOperation(value = "微信二维码/个人名片,图片上传")
    @RequestMapping(value = "uploadPicture", method = RequestMethod.POST)
    public QueryResponse uploadPicture(@RequestParam("file") MultipartFile file) {

        try{
            BaseUploadFile baseUploadFile=new BaseUploadFile(snowFlakeUtil,fileBasePath,uploadUtil);
            Map<String, Object> map = baseUploadFile.uploadFile(file,"image");
            Integer code=Integer.parseInt(String.valueOf(map.get("code")));
            String msg=String.valueOf(map.get("msg"));
            map.remove("code");
            map.remove("msg");
            return QueryResponse.setResData(map,code,msg);

        } catch (Exception ex) {
            log.error("api/departments/uploadPicture", ex);
            throw new BusinessException(ResultStatus.ERROR_PIC_UPLOAD.getErrorMsg(), ResultStatus.FAILOfficial);
        }
    }




    @ApiOperation(value = "查询用户所在部门顶级部门")
    @GetMapping(value = "queryTopDepartmentList")
    public QueryResponse queryTopDepartmentList(){
        QueryResponse queryResponse = new QueryResponse();
        try {
            List<DepartmentsChildResDto> list = departmentsService.queryTopParentList(getUserId());
            queryResponse.setData(list);
        } catch (Exception e) {
            log.error("api/departments/queryTopDepartmentList",e);
            return new QueryResponse(ResultStatus.FAIL.getErrorCode(), e.getMessage());
        }
        return queryResponse;
    }

    @ApiOperation(value = "查询用户所在部门顶级部门")
    @GetMapping(value = "queryTopDepartments")
    public QueryResponse queryTopDepartments(){
        QueryResponse queryResponse = new QueryResponse();
        try {
            YxUsers yxUsers = getUserBaseInfo();
            List<DepartmentsChildResDto> list = departmentsService.queryTopParentList(yxUsers.getId());
            List<Map> departments = new ArrayList<>();
            if(!CollectionUtils.isEmpty(list)){
                for(DepartmentsChildResDto dto : list){
                    Integer id = dto.getId();
                    Integer parentId = dto.getParentId();
                    Map map = new HashMap();
                    map.put("id",id);
                    map.put("parentId", "dept_" + parentId);
                    map.put("typeId", "dept_" + id);
                    map.put("name",dto.getName());
                    map.put("leaf",dto.getLeaf());
                    departments.add(map);
                }
            }
            queryResponse.setData(departments);
        } catch (Exception e) {
            log.error("api/departments/queryTopDepartmentList",e);
            return new QueryResponse(ResultStatus.FAIL.getErrorCode(), e.getMessage());
        }
        return queryResponse;
    }

    @ApiOperation(value = "查询指定部门下的直接子部门")
    @GetMapping(value = "selectChildDepartments")
   // @Cacheable(value = "department")
    public QueryResponse selectChildDepartments(@RequestParam(value = "deptId") Integer deptId){
        QueryResponse queryResponse = new QueryResponse();
        try {
            if(deptId <= 0){
                return new QueryResponse(ResultStatus.FAIL.getErrorCode(),"部门id不存在");
            }
            YxUsers yxUsers = getUserBaseInfo();
            List<DepartmentsChildResDto> list = departmentsService.selectChildDepartments(yxUsers.getId(), deptId);
            queryResponse.setData(list);
        } catch (Exception e) {
            log.error("api/departments/selectChildDepartments",e);
            return new QueryResponse(ResultStatus.FAIL.getErrorCode(), e.getMessage());
        }
        return queryResponse;
    }


    /**
     * 根据部门名称获取部门
     * @param name
     * @return
     */
    @ApiOperation(value = "根据部门名称获取部门")
    @GetMapping("queryDeptByName")
    public QueryResponse<List<DepartmentResDto>> queryDeptByName(@RequestParam("name")String name,
                                                                     @RequestParam(value = "num",required = false,defaultValue = "100") Integer num){
        return QueryResponse.setResData(departmentsService.queryDeptByName(name,num));
    }

    /**
     * 根据部门id获取父级部门集合
     * @param id
     * @return
     */
    @ApiOperation(value = "根据部门id获取父级部门集合")
    @GetMapping("queryParentDeptById")
    public QueryResponse<List<DepartmentResDto>> queryParentDeptById(@RequestParam("id")Integer id){
        return QueryResponse.setResData(departmentsService.queryParentDeptById(id));
    }




    @ApiOperation(value = "根据部门id查询其直接子部门和本部门成员")
    @GetMapping("queryDepartmentsAndUsersByDeptId")
    public QueryResponse queryDepartmentsAndUsersByDeptIds(@RequestParam(value = "deptId") Integer deptId, @RequestParam(value = "roleId") Integer roleId){
        QueryResponse queryResponse = new QueryResponse();
        try {
            if(deptId <= 0){
                return new QueryResponse(ResultStatus.FAIL.getErrorCode(),"部门id不存在");
            }
            if(roleId <= 0){
                return new QueryResponse(ResultStatus.FAIL.getErrorCode(),"角色id不存在");
            }
            YxUsers users = getUserBaseInfo();
            List<Map> list = departmentsService.selectDepartmentsAndUsersById(users.getId(), deptId, roleId);
            queryResponse.setData(list);
        } catch (Exception e) {
            log.error("api/departments/queryDepartmentsAndUsersByDeptId",e);
            return new QueryResponse(ResultStatus.FAIL.getErrorCode(), e.getMessage());
        }
        return queryResponse;
    }




    /**
     * 补全部门关系接口
     * @return
     */
    @GetMapping("complementDeptRelation")
    public QueryResponse complementDeptRelation(){
        if(departmentsService.complementDeptRelation()){
            return new QueryResponse();
        }
        return new QueryResponse(ResultStatus.FAIL);
    }


}
